/* Copyright 2012 Tobias Marschall
 *
 * This file is part of CLEVER.
 *
 * CLEVER is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * CLEVER is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with CLEVER.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <boost/tokenizer.hpp>
#include <boost/lexical_cast.hpp>

#include "VariationListParser.h"

using namespace std;

auto_ptr<vector<Variation> > VariationListParser::parse(istream& is, bool strip_chr_name) {
	auto_ptr<vector<Variation> > result(new vector<Variation>());
	typedef boost::tokenizer<boost::char_separator<char> > tokenizer_t;
	boost::char_separator<char> whitespace_separator(" \t");
	string line;
	int linenr = 0;
	while (getline(is,line)) {
		linenr += 1;
		tokenizer_t tokenizer(line, whitespace_separator);
		vector<string> tokens(tokenizer.begin(), tokenizer.end());
		if (tokens.size() != 4) {
			ostringstream oss;
			oss << "Error parsing variation list. Offending line: " << linenr;
			throw std::runtime_error(oss.str());
		}
		try {
			string chromosome = tokens[0];
			if (strip_chr_name) {
				if (chromosome.substr(0,3).compare("chr") == 0) {
					chromosome = chromosome.substr(3,chromosome.size() - 3);
				}
			}
			int coordinate1 = boost::lexical_cast<int>(tokens[1]);
			int coordinate2 = boost::lexical_cast<int>(tokens[2]);
			Variation::variation_type_t type;
			if (tokens[3].compare("DEL") == 0) {
				coordinate2 += 1;
				type = Variation::DELETION;
			} else if (tokens[3].compare("INS") == 0) {
				type = Variation::INSERTION;
			} else {
				ostringstream oss;
				oss << "Error parsing variation list: unknown variation type \"" << tokens[3] << "\". Offending line: " << linenr;
				throw std::runtime_error(oss.str());
			}
			result->push_back(Variation(chromosome,coordinate1,coordinate2,-1.0,type));
		} catch(boost::bad_lexical_cast &){
			ostringstream oss;
			oss << "Error parsing variation list. Offending line: " << linenr;
			throw std::runtime_error(oss.str());
		}
	}
	return result;
}
